package cn.elead.it.sso.system.controller;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.gitee.elead.api.ApiAssert;
import com.gitee.elead.api.ApiUtils;
import com.gitee.elead.api.emuns.ErrorCodeEnum;
import com.gitee.elead.web.api.ApiResponses;
import com.gitee.elead.web.controller.SuperController;

import cn.elead.it.sso.core.util.RSAUtil;
import cn.elead.it.sso.system.emuns.UserStatusEnum;
import cn.elead.it.sso.system.model.Permission;
import cn.elead.it.sso.system.model.User;
import cn.elead.it.sso.system.model.UserAvatar;
import cn.elead.it.sso.system.model.UserPwd;
import cn.elead.it.sso.system.service.IPermissionService;
import cn.elead.it.sso.system.service.IUserAvatarService;
import cn.elead.it.sso.system.service.IUserService;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

/**
 * <p>
 * 用戶信息rest服務
 * </p>
 *
 * @author luopeng
 */
@Api(tags = { "User" }, description = "用戶信息相关接口")
@RestController
@RequestMapping(value = "/api/user", produces = MediaType.APPLICATION_JSON_VALUE)
public class UserController extends SuperController {

	@Value("${file.host:http://sso.e-lead.cn/sso/avatar/}")
	private String host;

	@Value("${ras.privateKey}")
	private String privateKey;

	@Value("${ras.publicKey}")
	private String publicKey;

	@Autowired
	private IUserService userService;

	@Autowired
	private IUserAvatarService userAvatarService;

	@Autowired
	private IPermissionService permissionService;

	/**
	 * 查询用户信息信息
	 * 
	 * @param userName 姓名
	 * @param pinYin   姓名拼音
	 * @param account  账号
	 * @return List<User>
	 */
	@ApiOperation("查询用户信息信息")
	@GetMapping
	@ApiImplicitParams({ //
			@ApiImplicitParam(name = "userName", value = "姓名", paramType = "query"), //
			@ApiImplicitParam(name = "pinYin", value = "姓名拼音", paramType = "query"), //
			@ApiImplicitParam(name = "status", value = "是否在职", paramType = "query"), //
			@ApiImplicitParam(name = "account", value = "账号", paramType = "query")//
	}) //
	public ApiResponses<List<User>> findUsers(//
			@RequestParam(value = "userName", required = false) String userName, // 姓名
			@RequestParam(value = "pinYin", required = false) String pinYin, // 姓名拼音
			@RequestParam(value = "status", required = false) UserStatusEnum status, // 是否在职
			@RequestParam(value = "account", required = false) String account) {// 账号

		return findList(userName, pinYin, status, account);
	}

	/**
	 * 查询用户信息信息集合
	 * 
	 * @param userName 姓名
	 * @param pinYin   姓名拼音
	 * @param account  账号
	 * @return List<User>
	 */
	@ApiOperation("查询用户信息信息集合")
	@GetMapping("/list")
	@ApiImplicitParams({ //
			@ApiImplicitParam(name = "userName", value = "姓名", paramType = "query"), //
			@ApiImplicitParam(name = "pinYin", value = "姓名拼音", paramType = "query"), //
			@ApiImplicitParam(name = "status", value = "是否在职", paramType = "query"), //
			@ApiImplicitParam(name = "account", value = "账号", paramType = "query")//
	}) //
	public ApiResponses<List<User>> findList(//
			@RequestParam(value = "userName", required = false) String userName, // 姓名
			@RequestParam(value = "pinYin", required = false) String pinYin, // 姓名拼音
			@RequestParam(value = "status", required = false) UserStatusEnum status, // 是否在职
			@RequestParam(value = "account", required = false) String account) {// 账号

		List<User> list = userService.query() // 查询
				.like(ObjectUtils.isNotEmpty(userName), User::getUserName, userName)// 姓名
				.like(ObjectUtils.isNotEmpty(pinYin), User::getPinYin, pinYin)// 姓名拼音
				.like(ObjectUtils.isNotEmpty(account), User::getAccount, account)// 账号
				.eq(ObjectUtils.isNotEmpty(status), User::getStatus, status)// 是否在职
				.list();

		if (CollectionUtil.isNotEmpty(list)) {
			for (User user : list) {
				user.setPassword(null);
				user.setCardId(null);
			}
		}
		return success(list);
	}

	/**
	 * 分页查询用户信息信息
	 * 
	 * @param userName 姓名
	 * @param pinYin   姓名拼音
	 * @param account  账号
	 * @return IPage<User>
	 * @throws Exception
	 */
	@ApiOperation("分页查询用户信息信息")
	@GetMapping("/list/page")
	@ApiImplicitParams({ //
			@ApiImplicitParam(name = "userName", value = "姓名", paramType = "query"), //
			@ApiImplicitParam(name = "account", value = "账号", paramType = "query"), //
			@ApiImplicitParam(name = "permission", value = "是否管理员", paramType = "query"), //
			@ApiImplicitParam(name = "department", value = "部门", paramType = "query"), //
			@ApiImplicitParam(name = "status", value = "是否在职", paramType = "query"), //
			@ApiImplicitParam(name = "current", value = "当前页", paramType = "query"), //
			@ApiImplicitParam(name = "limit", value = "每页大小(默认每页条目20,最大条目数100)", paramType = "query") }) //
	public ApiResponses<IPage<User>> findPageList(User userQuery) throws Exception {// 账号

		IPage<User> page = userService.findPageList(this.getPage(), userQuery);

		Map<String, String> permissionMap = new HashMap<>();
		List<Permission> list = permissionService.list();
		if (CollectionUtil.isNotEmpty(list)) {
			permissionMap.putAll(list.stream().collect(Collectors.toMap(Permission::getId, Permission::getId)));
		}
		String currentUid = ApiUtils.currentUid();
		Permission p = permissionService.getById(currentUid);
		List<User> records = page.getRecords();
		if (CollectionUtil.isNotEmpty(records)) {
			for (User user : records) {
				if (ObjectUtil.isNotEmpty(p)) {
					user.setPassword(RSAUtil.decryptByPublicKey(user.getPassword(), publicKey));
				} else {
					user.setPassword(null);
					user.setCardId(null);
				}
				if (permissionMap.containsKey(user.getId())) {
					user.setPermission(true);
				}
			}
		}

		return success(page);
	}

	/**
	 * 根据ID查询用户信息
	 * 
	 * @param id 用户信息Id
	 * @return User
	 */
	@ApiOperation(value = "根据ID查询用户信息")
	@ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "用户信息id", required = true, paramType = "path") })
	@GetMapping("/{id}")
	public ApiResponses<User> findById(@PathVariable("id") String id) {
		User user = userService.getById(id);
		String avatarId = user.getAvatar();
		if (StrUtil.isNotBlank(avatarId)) {
			UserAvatar userAvatar = userAvatarService.getById(avatarId);
			if (ObjectUtil.isNotEmpty(userAvatar)) {
				user.setAvatar(userAvatar.getUrl());
			}
		} else {
			int randomInt = RandomUtil.randomInt(50);
			user.setAvatar(host + randomInt + ".jpg");
		}
		user.setCardId(null);
		user.setPassword(null);
		return success(user);
	}

	/**
	 * 添加用户信息信息
	 * 
	 * @param User 用户信息
	 * @return User
	 * @throws Exception
	 */
	@ApiOperation(value = "添加用户信息信息")
	@PostMapping
	public ApiResponses<Void> create(@RequestBody User user) throws Exception {

		User u = userService.query().eq(User::getAccount, StrUtil.trim(user.getAccount())).getOne();
		ApiAssert.isNull(ErrorCodeEnum.BAD_REQUEST.convert("用户已经存在"), u);
		int count = userService.count();
		String id = count * 10 + 1 + "";
		user.setId(id);
		user.setType(1);
		user.setStatus(UserStatusEnum.DISABLE);
		user.setEntryDate(new Date());
		// 初始密码
		String password = user.getPassword();
		if (StrUtil.isBlank(password)) {
			password = "123456";
		}
		// password = Md5Crypt.apr1Crypt(password, id);
		password = RSAUtil.encryptByPrivateKey(password, privateKey);
		user.setPassword(password);
		userService.save(user);
		return success(HttpStatus.CREATED);
	}

	/**
	 * 修改用户信息信息
	 * 
	 * @param id   用户信息Id
	 * @param User 用户信息
	 * @return User
	 */
	@ApiOperation(value = "修改用户信息信息")
	@ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "用户信息id", required = true, paramType = "path") })
	@PutMapping("/{id}")
	public ApiResponses<Void> update(@PathVariable("id") String id, @RequestBody User User) {
		User.setId(id);
		userService.updateById(User);
		return success();
	}

	/**
	 * 删除用户信息信息
	 * 
	 * @param id 用户信息Id
	 * @return
	 */
	@ApiOperation(value = "删除用户信息信息")
	@ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "用户信息id", required = true, paramType = "path") })
	@DeleteMapping("/{id}")
	public ApiResponses<Void> delete(@PathVariable("id") String id) {
		userService.removeById(id);
		return success(HttpStatus.NO_CONTENT);
	}

	/**
	 * 修改头像
	 * 
	 * @param file
	 * @return
	 */
	@ApiOperation("修改头像")
	@PostMapping(value = "/updateAvatar")
	public ApiResponses<Void> updateAvatar(@RequestParam MultipartFile file) {
		userService.updateAvatar(file);
		return success(HttpStatus.NO_CONTENT);
	}

	/**
	 * 修改密码
	 * 
	 * @param user
	 * @return
	 * @throws Exception
	 */
	@ApiOperation("修改密码")
	@PostMapping(value = "/updatePass")
	@Transactional
	public ApiResponses<Void> updatePass(@RequestBody UserPwd userPwd) throws Exception {

		String sid = userPwd.getSid();
		ApiAssert.notNull(ErrorCodeEnum.BAD_REQUEST.convert("用户ID不能为空"), sid);

		User user = userService.getById(sid);
		ApiAssert.notNull(ErrorCodeEnum.BAD_REQUEST.convert("用户不存在"), user);

		String newPassword = userPwd.getNewPassword();
		ApiAssert.notNull(ErrorCodeEnum.BAD_REQUEST.convert("密码不能为空"), newPassword);

		// 修改密码
		String password = RSAUtil.encryptByPrivateKey(newPassword, privateKey);

		userService.update().set(User::getPassword, password).set(User::getPasswordStatus, 1)
				.eq(User::getId, user.getId()).execute();
		return success(HttpStatus.NO_CONTENT);
	}

	/**
	 * 查询权限
	 * 
	 * @param user
	 * @return
	 */
	@ApiOperation("查询权限")
	@GetMapping(value = "/permission/me")
	public ApiResponses<Boolean> findPermission() {
		String currentUid = ApiUtils.currentUid();
		Permission p = permissionService.getById(currentUid);
		if (ObjectUtil.isEmpty(p)) {
			return success(false);
		}
		return success(true);
	}

	/**
	 * 修改权限
	 * 
	 * @param user
	 * @return
	 */
	@ApiOperation("修改权限")
	@PutMapping(value = "/permission/{id}")
	@Transactional
	public ApiResponses<Void> updatePermission(@PathVariable("id") String id) {
		Permission p = permissionService.findById(id);
		if (ObjectUtil.isNotEmpty(p) && p.getDeleted() == 0) {
			permissionService.delete().eq(Permission::getId, id).execute();
		} else if (ObjectUtil.isNotEmpty(p)) {
			permissionService.updateDelById(id);
		} else {
			Permission entity = new Permission();
			entity.setId(id);
			permissionService.save(entity);
		}
		return success(HttpStatus.NO_CONTENT);
	}

	@Scheduled(cron = "0 0 2 * * ?")
	@GetMapping("/sync")
	public void syncUser() {
		userService.syncUser();
	}

	@Scheduled(cron = "0 0 4 * * ?")
	@GetMapping("/initPassword")
	public void initPassword() throws Exception {
		userService.initPassword();
	}

}
